package mc

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"time"
)

//
func MiddlewareLogToFile(c *gin.Context)  {
	defer func() {
		if r := recover(); r != nil {
			errMsg := fmt.Sprintf("日志写入错误（中间件）: %s", r)
			WriteErrStackLog(c,errMsg)
		}
	}()
	// 开始时间
	startTime := time.Now()
	if c.ContentType() == "multipart/form-data" {
		_ = c.Request.ParseMultipartForm(1048576)
	} else {
		_ = c.Request.ParseForm()
	}
	// 处理请求
	c.Next()

	var result *Result
	if err := GetErrResult(c); err != nil{
		// 错误结果
		result = err
	}else {
		// 正常结果
		httpState := c.Writer.Status()
		code := ""
		if httpState != 200 {
			code = cast.ToString(httpState * 10000)
		}else{
			code = option.Response.SuccessCodeValue
		}
		result = &Result{
			HttpStatus: httpState,
			Code:       fmt.Sprintf("%s", code),
			Message:    "",
			LogLevel:   logrus.InfoLevel,
		}
	}
	renderType := result.RenderType
	if renderType == RenderTypeDefault {
		renderType = GetRenderType(c)
	}
	requestUrl := "http://"
	if c.Request.TLS != nil{
		requestUrl = "https://"
	}
	requestUrl = fmt.Sprintf("%s%s%s", requestUrl, c.Request.Host, c.Request.RequestURI)
	logFields := &LogFields{
		Type: "request",
		ExecuteTime: fmt.Sprintf("%.2f", float64(time.Now().Sub(startTime)) / float64(time.Millisecond)) + " ms",
		StatusCode: result.HttpStatus,
		Code:        result.Code,
		Info: &LogRequestFields{
			Method:  	 c.Request.Method,
			ContentType: c.ContentType(),
			RequestIp:   c.ClientIP(),
			RequestUri:  requestUrl,
			RequestData: c.Request.Form,
			RenderType: renderType,
		},
	}

	if result.IsInfo {
		result.LogLevel = logrus.WarnLevel
	}

	logger := GetDefaultContextLogger(c).WithCustomFields(&logFields)
	switch result.LogLevel {
	case logrus.DebugLevel:
		logger.Debug(result.Message)
	case logrus.InfoLevel:
		logger.Info(result.Message)
	case logrus.WarnLevel:
		logger.Warn(result.Message)
	case logrus.ErrorLevel:
		logger.Error(result.Message)
	case logrus.FatalLevel:
		logger.Panic(result.Message)
	case logrus.PanicLevel:
		logger.Panic(result.Message)
	}

	switch result.LogLevel {
	case logrus.ErrorLevel, logrus.PanicLevel, logrus.FatalLevel:
		WriteErrStackLog(c, result.Message)
	}

}